﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using Ini;

namespace TwipPlays
{
    public partial class Form1 : Form
    {

        private Thread processThread;
        private IRCThread ircThread;

        private string server;
        private string user;
        private string auth;
        private string channel;

        private bool votingEnabled;
        private string votingLeftTerm;
        private string votingRightTerm;
        private int votingBounds;
        private int votingMode = 0;

        private int maxActions;

        private string started_title = "TwipPlays - *CLIENT STARTED*";
        private string stopped_title = "TwipPlays";


        // Delegates
        public delegate void AddAction(string user, string action);
        public AddAction addActionDelegate;

        public delegate void AddVoteAction(string actStr, string votes);
        public AddVoteAction addVoteActionDelegate;

        public delegate void VoteActionClear();
        public VoteActionClear voteActionClearDelegate;

        public delegate void SetVotedAction(string votedAction);
        public SetVotedAction setVotedActionDelegate;

        public delegate void UpdateVoting(int count);
        public UpdateVoting updateVotingDelegate;

        public delegate void ChangeVotingMode(int mode);
        public ChangeVotingMode changeVotingModeDelegate;

        public Form1()
        {
            InitializeComponent();

            this.applyConfig();

            
            // Set up the DataGridView


            // Define delegates
            this.addActionDelegate = new AddAction(AddActionMethod);
            this.addVoteActionDelegate = new AddVoteAction(AddVoteActionMethod);
            this.voteActionClearDelegate = new VoteActionClear(VoteActionClearMethod);
            this.setVotedActionDelegate = new SetVotedAction(SetVotedActionMethod);
            this.updateVotingDelegate = new UpdateVoting(UpdateVotingMethod);
            this.changeVotingModeDelegate = new ChangeVotingMode(ChangeVotingModeMethod);

        }

        private void form_closed(object sender, FormClosedEventArgs e)
        {

            if (this.processThread != null && this.processThread.IsAlive)
            {

                // Close the process
                this.ircThread.CloseIRC();

                // Terminate the thread
                this.processThread.Abort();
                this.processThread.Join();

            }

        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }

        private void menu_item_clicked(object sender, EventArgs e)
        {

            System.Diagnostics.Debug.WriteLine(sender.ToString() + " menu action clicked");
            string source = sender.ToString();

            if (source == "Start Client")
            {

                this.startClientToolStripMenuItem.Checked = true;

                this.startClientToolStripMenuItem.Text = "Shutdown Client";
                this.Text = this.started_title;


                // Define & start the thread
                if (this.processThread == null || !( this.processThread.IsAlive) )
                {

                    this.ircThread = new IRCThread(this);

                    this.processThread = new Thread(new ThreadStart(this.ircThread.StartIRC));
                    this.processThread.Start();

                }

            }
            else if (source == "Shutdown Client")
            {

                this.startClientToolStripMenuItem.Checked = false;

                this.startClientToolStripMenuItem.Text = "Start Client";
                this.Text = this.stopped_title;


                // Check if we are alive
                if (this.processThread != null && this.processThread.IsAlive)
                {

                    // Close the process
                    this.ircThread.CloseIRC();

                    this.processThread.Abort();
                    this.processThread.Join();

                    // Reset the interface
                    this.ChangeVotingModeMethod(0);

                }

            }
            else if (source == "Exit")
            {

                this.Close();

            }
            else if (source == "Server")
            {

                Server dialog = new Server();
                dialog.FormClosed += this.HandleSettingsDialogClosed;
                dialog.Show();

            }
            else if (source == "Environment")
            {

                Environment dialog = new Environment();
                dialog.FormClosed += this.HandleSettingsDialogClosed;
                dialog.Show();

            }
            else if (source == "Keys")
            {

                Keys dialog = new Keys();
                dialog.FormClosed += this.HandleSettingsDialogClosed;
                dialog.Show();

            }
            else if (source == "Set Title")
            {

                SetTitle dialog = new SetTitle();
                dialog.FormClosed += this.HandleSettingsDialogClosed;
                dialog.Show();

            }
            else if (source == "Voting")
            {

                Voting dialog = new Voting();
                dialog.FormClosed += this.HandleSettingsDialogClosed;
                dialog.Show();

            }

        }

        // Handle when dialogs close
        protected void HandleSettingsDialogClosed(object sender, EventArgs e)
        {

            applyConfig();

        }

        // IRC Actions
        public void AddActionMethod(string user, string action)
        {

            // Add to the DataGridView
            System.Diagnostics.Debug.WriteLine("AddAction: " + user + ", " + action);

            if (this.votingMode == 0)
            {

                if (this.action_grid.Rows.Count >= this.maxActions && this.maxActions >= 1)
                    this.action_grid.Rows.RemoveAt(this.action_grid.Rows.Count - 1);

                string[] newAction = new string[] { user, action };
                if (this.action_grid.Rows.Count > 0)
                    this.action_grid.Rows.Insert(0, newAction);
                else
                    this.action_grid.Rows.Add(newAction);

            }

        }

        public void AddVoteActionMethod(string actStr, string votes)
        {

            // If the action isn't in the grid, add it
            bool found = false;
            DataGridViewCell foundCell = null;
            foreach (DataGridViewRow row in this.action_grid.Rows )
            {

                if( row.Cells[0].Value.ToString().Equals( actStr ) )  
                {

                    found = true;
                    foundCell = row.Cells[1];
                    break;

                }

            }

            // Add or update
            if (!found)
            {

                string[] newAction = new string[] { actStr, votes };
                this.action_grid.Rows.Insert(0, newAction);

            }
            else if (foundCell != null)
                foundCell.Value = votes;

            // Finally, sort the grid
            this.action_grid.Sort(this.action_grid.Columns[1], ListSortDirection.Descending);

        }

        public void VoteActionClearMethod()
        {

            // Clear the action grid
            this.action_grid.Rows.Clear();

        }

        public void SetVotedActionMethod(string votedAction)
        {

            this.voted_action.Text = votedAction;

        }

        public void UpdateVotingMethod(int count)
        {

            if (count < 0)
            {


                int newValue = 100 - ((int)(((double)-(count) / (double)this.votingBounds) * 100));

                this.vote_right_progress.Value = 0;
                this.vote_left_progress.Value = newValue;

            }
            else
            {

                int newValue = (int)(((double)(count) / (double)this.votingBounds) * 100);

                this.vote_left_progress.Value = 100;
                this.vote_right_progress.Value = newValue;

            }

        }

        public void ChangeVotingModeMethod(int mode)
        {

            this.votingMode = mode;

            if (mode == 0)
            {

                this.vote_left_progress.Value = 100;
                this.vote_left_term.ForeColor = Color.Red;

                this.vote_right_progress.Value = 0;
                this.vote_right_term.ForeColor = Color.Gray;

                // Clear the action grid
                this.action_grid.Rows.Clear();

                this.voted_action.Visible = false;
                this.voted_action.Text = "";

            }
            else if (mode == 1)
            {

                this.vote_left_progress.Value = 100;
                this.vote_left_term.ForeColor = Color.Gray;

                this.vote_right_progress.Value = 0;
                this.vote_right_term.ForeColor = Color.Green;

                // Clear the action grid
                this.action_grid.Rows.Clear();

                this.voted_action.Visible = true;
                this.voted_action.Text = "";


            }

        }

        private void applyConfig()
        {

            IniFile ini = new IniFile("irc_parser/config.ini");

            string title = ini.IniReadValue("main", "title");
            this.server = ini.IniReadValue("server", "server");
            this.user = ini.IniReadValue("server", "user");
            this.auth = ini.IniReadValue("server", "auth");
            this.channel = ini.IniReadValue("server", "channel");
            this.votingEnabled = (ini.IniReadValue("voting", "votingEnabled") == "true");
            this.votingLeftTerm = ini.IniReadValue("voting", "votingLeftTerm").ToUpper();
            this.votingRightTerm = ini.IniReadValue("voting", "votingRightTerm").ToUpper();

            string votingBoundsStr = ini.IniReadValue("voting", "votingBounds");
            string maxActionsStr = ini.IniReadValue("voting", "maxActions");
            int.TryParse(votingBoundsStr, out this.votingBounds);
            int.TryParse(maxActionsStr, out this.maxActions);


            this.main_title.Text = title;
            this.voted_action.Text = "";

            this.vote_left_term.Text = this.votingLeftTerm;
            this.vote_left_term.ForeColor = Color.Red;

            this.vote_right_term.Text = this.votingRightTerm;
            this.vote_right_term.ForeColor = Color.Gray;

            if (!(this.votingEnabled))
            {

                this.vote_left_term.Visible = false;
                this.vote_left_progress.Visible = false;
                this.vote_right_term.Visible = false;
                this.vote_right_progress.Visible = false;

                this.voted_action.Visible = false;

            }
            else
            {

                this.vote_left_term.Visible = true;
                this.vote_left_progress.Visible = true;
                this.vote_right_term.Visible = true;
                this.vote_right_progress.Visible = true;

                this.voted_action.Visible = true;

            }

        }

    }
}
